import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter_soundmagus/util.dart';
import 'package:flutter_soundmagus/util/util.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get.dart';
import 'package:rxdart/subjects.dart';

import '../common/global.dart';
import 'model.dart';

part 'msg_data.dart';

int kTimeCostSec = 20; //预计加载数据秒数
int kRetryTimes = 3; //重试次数
int kPackLen = 20; //每包长度
int kDataMaxLen = 6120; //306个包，
int kDataPart1Len = 1926; //Part1的数据长度

class MsgParser {
  int _index = 0; //第几次
  int get index => _index; //第几次
  set index(int v) {
    _index = v;
    _retryTimes = 0;
  }

  ///写入数据流
  final onWrite = PublishSubject<List<int>>();

  ///读取数据流
  final onReceived = PublishSubject<List<int>>();

  ///上传取得数据刷新UI，是否需要发送数据，
  final onFinished = PublishSubject<bool>();

  MsgParser() {
    onReceived.listen((value) {
      _data.addAll(value);
    });
  }

  static MsgParser instance = MsgParser();

  List<int> _data = [];

  DateTime _timeStart = DateTime.now();
  int _timeCost = 0; //花费秒数
  int _timeCostCurrentPart = 0; //当前数据部分的花费秒数
  int _retryTimes = 0; //重试次数
  bool _isFoundFirstPack = false; //是否找到了第一包
  bool _isDataSending = false; //正在发送接收中

  void _filterData() {
    var buffer = _data;
    var len = _data.length;
    for (int i = 0; i < len; i++) {
      if (len - i < kPackLen) {
        break;
      }
      if (buffer[i] == 0xaa &&
          buffer[i + 1] == 0x00 &&
          buffer[i + 2] == 0x00 &&
          buffer[i + 17] == 0xff &&
          buffer[i + 18] == 0xff &&
          buffer[i + 19] == 0x55) {
        var data = _data.sublist(i, len - i);
        _data = data;
        _isFoundFirstPack = true;
        logger.d("已找到有效的第一包");
      }
    }
  }

  void _uploadLog() {}

  void timerAction() {
    _timeCost++;
    _timeCostCurrentPart++;

    logger.d("长度${_data.length} 现有数据>>==${list2Hex(_data)}");

    if (_data.length >= kDataMaxLen) {
      _closeTimer();

      var time = DateTime.now().difference(_timeStart).inSeconds;
      logger.d("花费时间===>$time");

      //bytes = 0xaa00ffffffffffffffffffffffffffffff55}
      //找第一包
      _filterData();

      parse3(_data, false, true);
      _refresh(shouldSendData: false);
      _uploadLog();
    }
    if (_timeCost > (kTimeCostSec * kRetryTimes) &&
        _data.length < kDataMaxLen) {
      logger.d("超时$_timeCost");
      if (_hasLoadedPrefer()) {
        _processParse();
      } else {
        _closeTimer();
        onFinished.add(false);
        Future.delayed(Duration(milliseconds: 100),
            () => Fluttertoast.showToast(msg: 'Read Failed!'));
      }
      _uploadLog();
    }

    if (_timeCostCurrentPart > kTimeCostSec && _data.length < kDataMaxLen) {
      if (_hasLoadedPrefer()) {
        _processParse();
        _uploadLog();
        return;
      }
      //超时重试
      _retryTimes++;
      logger.d("重试次数 $_retryTimes");

      _data = [];
      _sendData(index);
    }
  }

  /// 加载到预期数据
  bool _hasLoadedPrefer() {
    return (_data.length > (kDataMaxLen * 0.95));
  }

  ///  接入解析流程
  void _processParse() {
    _closeTimer();

    logger.d("丢包，但是长度大于95%%，进入解析 当前长度 ${_data.length}");
    _filterData();

    parse3(_data, false, true);
    _refresh(shouldSendData: false);
  }

  Timer? _timer;
  _startTimer() {
    _closeTimer();
    _timer = Timer.periodic(Duration(seconds: 1), (timer) => timerAction());
    _isDataSending = true;
  }

  void start() async {
    index = 0;

    _timeStart = DateTime.now();
    _timeCost = 0;
    _retryTimes = 0;

    _data = [];
    _sendData(index);
    _startTimer();
  }

  _closeTimer() {
    _timer?.cancel();
    _timer = null;
    _index = 0;
    _isDataSending = false;
    _timeCost = 0;
  }

  void recive(List<int> data) {
    _data.addAll(data);
  }

  void _sendData(int index) {
    _timeCostCurrentPart = 0;

    List<int> data = List.generate(14, (i) => 0);
    int i = 0;
    data[i++] = 0xaa;
    data[i++] = 0x55;
    data[i++] = 0x47;
    data[i++] = 0x45;
    data[i++] = 0x54;
    data[i++] = 0x44;
    data[i++] = 0x53;
    data[i++] = 0x50;
    data[i++] = 0x54;
    data[i++] = 0x59;
    data[i++] = 0x55;
    data[i++] = 0x55;
    data[i++] = index;

    onWrite.add(data);
  }

  void parse(List<int> data) {
    parse3(data, false, false);
  }

  void parse3(List<int> data, bool shouldSendData, bool isUpload) {
    if (data.length < 14) {
      return;
    }

    var bytes = data;

    // ignore: non_constant_identifier_names
    int package_len = isUpload ? kPackLen : 12;
    for (int i = 0;
        i < (data.length / package_len * package_len);
        i += package_len) {
      var pack = data.sublist(i, i + package_len);
      // ignore: non_constant_identifier_names
      late List<int> sub_data;
      if (isUpload) {
        //0xaa00 aa83f0c101000000000001000000 ff55
        var buffer = pack;
        if (pack.length >= package_len) {
          if ((buffer[0] != 0xaa || buffer[kPackLen - 1] != 0x55)) {
            continue;
          }
          sub_data = []..addAll(zf_header_buffer);
          sub_data.addAll(pack.sublist(3, 3 + 14)); //拼接头
        } else {
          continue;
        }
      } else {
        sub_data = []..addAll(zf_header_buffer);
        sub_data.addAll(pack); //拼接头
      }

      var baseMsg = ZFBaseMsg().parseFromData<ZFBaseMsg>(sub_data)!;
      var cmd = baseMsg.cmd.value;
      var buffer = sub_data;
      logger.d("cmd=${cmd.toHexString()}, sub_data=${sub_data.toHexString()}");
      if (buffer[3] == 0x83 && buffer[4] == 0xf0) {
        //合频
        ZFSummingMsg msg =
            ZFSummingMsg().parseFromData<ZFSummingMsg>(sub_data)!;
        logger.d("summing data $msg");

        var ch = msg.ch.value - 0xc1;
        msg.ch.value = ch;
        if (ch >= kChCount) {
          continue;
        }

        for (int i_in = 0; i_in < kChCountIn; i_in++) {
          var ls = [
            msg.ch1,
            msg.ch2,
            msg.ch3,
            msg.ch4,
            msg.ch5,
            msg.ch6,
            msg.ch7,
            msg.ch8
          ];
          int chv = ls[i_in].value;
          if (chv > 0) {
            DataMng().summingModel.highModel.chs[ch][i_in] = (i_in + 1);
          }
        }
      } else if (cmd == ZFDelayMsg().cmd.value) {
        /**延时协议
             2 通道：CH1发0xc1，CH2发0xc2,CH3发0xc3，CH4发0xc4，CH5发0xc5，CH6发0xc6，CEN发0xc7，SUB发0xc8
             3 4 延时参数：0x00为0毫秒，0x46为7毫秒，步进0.1毫秒（即：UI显示0.1毫秒实际发送的值为10，显示最大10毫秒实际发送的值为1000)
             */
        //0xCC, 通道(0xC1~0xC6), 延时(0x0000~0x03E8)
        ZFDelayMsg msg = ZFDelayMsg().parseFromData<ZFDelayMsg>(sub_data)!;
        logger.d("delay data $msg");

        var ch = msg.ch.value - 0xc1;
        var delay = msg.delay.value / 100.0;

        var timeDelayModel = DataMng().advancedModel.timeDelay;
        timeDelayModel.timeDelays[ch] = delay;
      } else if (cmd == ZFVolumeMsg().cmd.value) {
        //音量协议
        //0xDB, 通道(0xC1~0xC6), 是/否静音(0x00否,0x01是), dB音量(0x0000~0x03B6)
        ZFVolumeMsg msg = ZFVolumeMsg().parseFromData<ZFVolumeMsg>(sub_data)!;
        logger.d("volume data $msg");

        var levelModel = DataMng().advancedModel.level;
        var ch = msg.ch.value - 0xc1;
        levelModel.items[ch].volume = -msg.volume.value ~/ kVolumeRadio;
        //levelModel.items[ch].paraphase = bytes[i+5];
        levelModel.items[ch].mute = msg.mute.value == 0x01;
      } else if (cmd == ZFParaphaseMsg().cmd.value) {
        ZFParaphaseMsg msg =
            ZFParaphaseMsg().parseFromData<ZFParaphaseMsg>(sub_data)!;
        logger.d("相位 data $msg");

        var levelModel = DataMng().advancedModel.level;
        int ch = msg.ch.value - 0xc1;
        levelModel.items[ch].paraphase = msg.paraphase.value > 0;
      } else if (cmd == ZFTotalVolumeMsg().cmd.value) {
        //发送总音量
        //0xEE, 是/否静音(0x00否,0x01是), dB音量(0x0000~0x03B6)
        ZFTotalVolumeMsg msg =
            ZFTotalVolumeMsg().parseFromData<ZFTotalVolumeMsg>(sub_data)!;
        logger.d("totalvolume data $msg");

        var levelModel = DataMng().advancedModel.level;
        levelModel.totalModel.volume = -msg.volume.value ~/ kVolumeRadio;
        levelModel.totalModel.mute = (msg.mute.value == 0x01);
      } else if (cmd == 0xdd || cmd == 0xde) {
        // 发送分频器（CrossOver页面）
        //0xDD, 通道(0xC1~0xC6), H类型(0x00 bessel,0x01 btr-w,0x02 link-r),H斜率(0x00 6,0x01 12,0x02 24,0x03 48),H频率(0x0014~0x4E20)
        //0xDE, 通道(0xC1~0xC6), L类型(0x00 bessel,0x01 btr-w,0x02 link-r),L斜率(0x00 6,0x01 12,0x02 24,0x03 48),L频率(0x0014~0x4E20)
        ZFXoverMsg msg = ZFXoverMsg().parseFromData<ZFXoverMsg>(sub_data)!;
        logger.d("xover data $msg");

        var xoverModel = DataMng().xoverModel;

        int ch = msg.ch.value - 0xc1;
        bool isHigh = msg.cmd.value == 0xdd;
        int bypass = bytes[i + 2];
        int butter_W = msg.type.value;
        int slope = msg.xielv.value;
        int freq = msg.freq.value;

        var xoverItemModel = xoverModel.itemModel(selectCH: ch);
        late XoverItemHighLowModel xoverItemHighLowModel;
        if (isHigh) {
          //高通
          xoverItemHighLowModel = xoverItemModel.high;
        } else {
          //低通
          xoverItemHighLowModel = xoverItemModel.low;
        }

        xoverItemHighLowModel = xoverItemHighLowModel.copyWith(
            isBypass: bypass == 0x00, type: butter_W, slope: slope, freq: freq);
      } else if (cmd == 0xaa || cmd == 0xab) {
        //发送通道频率、Q值、增益（EQ页面）
        //0xAA~0xAB(单通道、联调), 通道(0xC1~0xC6),点(0x00~0x1E),频率(0x0014~0x4E20), Q值(0x0005~0x07D0), 增益(0x0000~0x0190)
        ZFEqMsg msg = ZFEqMsg().parseFromData<ZFEqMsg>(sub_data)!;
        logger.d("eq data $msg");

        var eqModel = DataMng().eqModel;

        int ch = msg.ch.value - 0xc1;
        int pd = msg.pd.value;
        int CH = msg.gain.value ~/ 10;
        int hz = msg.freq.value;
        int Q = msg.q.value;

//            assert(ch>=0 && ch<=0x0190);
//            assert(Q>= 0x0005 && Q<=0x07D0);
//            assert(hz >=20 && hz<=0x4E20);
//            assert(pd>=0 && pd <= 0x1E);
        if (Q < 0 || Q > 0x07D0) {
          Q = 720;
        }
        if (pd < 0 || pd > 0x1E) {
          return;
        }
        var eqItemModel = eqModel.getItemModel(ch, pd);

        eqItemModel.ch = CH - 20;
        eqItemModel.freq = hz;
        eqItemModel.q = Q / 100.0;
      }
    }
    _refresh(shouldSendData: shouldSendData);
  }

  _refresh({bool shouldSendData = false}) {
    onFinished.add(shouldSendData);
  }

  static void done({bool sendData = false}) {
    MsgParser.instance.onFinished.add(sendData);
  }

  List<int> hexString2Data(String command) {
    List<int> list = [];
    for (int i = 0; i <= command.length - 2; i += 2) {
      final hex = command.substring(i, i + 2);
      final number = int.parse(hex, radix: 16);
      list.add(number);
    }
    return list;
  }

  String list2Hex(List<int> data) {
    return data.map((b) => '${b.toRadixString(16).padLeft(2, '0')}').join();
  }

  /// 解析指令文件
  /// @param str <#path description#>
  void parseWithString(String str) {
    List<int> dataAll = [];
    var cmds = str.split('\n'); //['aa55ddc60001006e000000000000']
    if (cmds.isEmpty && str.isNotEmpty) {
      //兼容某些情况可能没有换行符的时
      for (var i = 0; i < str.length; i += 28) {
        try {
          var line = str.substring(i, 28);
          cmds.add(line);
        } catch (e) {}
      }
    }
    for (var cmd in cmds) {
      var line = cmd;
      line = line.removeAllWhitespace;
      if (line.length < 28) continue;
      var data = hexString2Data(line);
      if (data.length > 2) {
        //去掉aa55
        data = data.sublist(2); //截取后每条指令长度=12
      }
      dataAll.addAll(data);
    }
    parse3(dataAll, true, false);
  }

  void testUpload() {
    start();
    var data = hexString2Data(kTestMsgData);
    recive(data);
  }

  void uploadLog() {}
}

mixin MsgParserRefreshMixin {
  ///是否发送数据
  bool needSendData = false;
  void observeRefresh() {
    MsgParser.instance.onFinished.listen((v) => onFinished(v), onError: (v) {
      print('MsgParser.instance.onFinished.listen ${v}');
    });
  }

  ///上传数据结束
  void onFinished(bool needSendData) {
    this.needSendData = needSendData;
    refreshData(needSendData);
    refreshState(needSendData);
  }

  ///刷新数据
  @mustCallSuper
  void refreshData(bool needSendData) {}

  ///刷新UI
  @mustCallSuper
  void refreshState(bool needSendData) {}
}
